﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.Net;

namespace scomA3proj
{
    public class MultithreadedHttpRequests_James : IMultithreadedHttpRequests_James
    {
        private List<string> Urls;
        private string[] responses;

        /// <summary>
        /// Gets content of specified web pages.
        /// </summary>
        /// <param name="urls">The list of urls.</param>
        /// <param name="numThreads">Creates numThreads threads to pipeline http requests.</param>
        /// <returns>List of responses in the same order of the original urls.</returns>
        public List<string> getHttpResponses(List<string> urls, int numThreads)
        {
            counter = 0;
            ServicePointManager.DefaultConnectionLimit = numThreads;
            this.Urls = urls;
            responses = new string[urls.Count];
            List<Thread> threads = new List<Thread>();
            //for numThreads, start a thread.
            for (int i = 0; i < numThreads; i++)
            {
                Thread bgw = new Thread(new ParameterizedThreadStart(bgw_DoWork));
                bgw.Start();
                threads.Add(bgw);
            }
            //join all threads.
            for (int i = 0; i < numThreads; i++)
            {
                threads[i].Join();
            }
            return responses.ToList();
        }

        /// <summary>
        /// Performs the work of obtaining a response(thread entry).
        /// Continues until the url list is exhausted.
        /// </summary>
        /// <param name="sender"></param>
        void bgw_DoWork(object sender)
        {
            while (true)
            {
                int index = getNext();
                if (index == -1) break;
                string s = Urls[index];
                responses[index] = HttpRequestWrapper.getResponse(s);
            }
        }
        int counter = 0;
        /// <summary>
        /// Gets the next url index.
        /// </summary>
        /// <returns>-1 if the list is exhausted.</returns>
        int getNext()
        {
            int res = 0;
            lock (this)
            {
                res = counter;
                counter++;
            }
            if (res >= Urls.Count) 
                return -1;

            return res;
        }
    }
}
